package com.top.web.hooker.search;

import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;

import com.top.web.hooker.common.GroupList;


public class GroupAdapters
{
    public static abstract class FilterListGroupAdapter<TKey, TValue> extends ListGroupAdapter implements Filterable, Filters.GroupFilterLinstener<TKey, TValue>
    {
        private Filters.PhoneticGroupFilterable<TKey, TValue> _filter;

        public FilterListGroupAdapter(ISearch<TKey, TValue>... array)
        {
            _filter = new Filters.PhoneticGroupFilterable<TKey, TValue>(array);
            _filter.setFilterLinstener(this);
        }

        public GroupList<TKey, TValue> getGroupList()
        {
            return _filter.getGroupList();
        }

        public Filters.PhoneticGroupFilterable<TKey, TValue> getFilterable()
        {
            return _filter;
        }

        @Override
        public synchronized int getGroupCount()
        {
            return _filter.getGroupList().size();
        }

        @Override
        public synchronized Object getGroup(int i)
        {
            return _filter.getGroupList().getKey(i);
        }

        @Override
        public synchronized Object getGroupItem(int group, int i)
        {
            synchronized (_filter)
            {
                return _filter.getGroupList().get(_filter.getGroupList().getKey(group), i);
            }
        }

        @Override
        public synchronized int getGroupItemCount(int group)
        {
            int gountCount = _filter.getGroupList().get(_filter.getGroupList().getKey(group)).size();
            int max = getGroupItemMax(group);

            if (max == -1)
                return gountCount;
            else
                return Math.min(gountCount, max);
        }

        public abstract int getGroupItemMax(int group);

        @Override
        public Filter getFilter()
        {
            return _filter.getFilter();
        }

        @Override
        public void onReady(GroupList<TKey, TValue> list)
        {
            if (list.size() > 0)
                notifyDataSetChanged();
            else notifyDataSetInvalidated();
        }

        @Override
        public void onCompleted()
        {
            new Handler(Looper.getMainLooper()).post(new Runnable()
            {
                @Override
                public void run()
                {
                    notifyDataSetChanged();
                }
            });
        }

        @Override
        public void onUpdate()
        {
            new Handler(Looper.getMainLooper()).post(new Runnable()
            {
                @Override
                public void run()
                {
                    notifyDataSetChanged();
                }
            });
        }
    }

    public static class Index
    {
        public int Index;
        public int Group;
    }

    public static abstract class ListGroupAdapter extends BaseAdapter
    {
        public abstract int getGroupCount();

        public abstract int getItemCount();

        public abstract Object getGroup(int i);

        public abstract View getGroupItemView(int group, int i, View view, ViewGroup groupView);

        public abstract View getHeaderView(int group, View headerView);

        public abstract Object getGroupItem(int group, int i);

        public abstract int getGroupItemCount(int group);

        @Override
        public int getCount()
        {
            return getGroupCount() + getItemCount();
        }

        @Override
        public Object getItem(int i)
        {
            return getGroup(i / 2);
        }

        @Override
        public long getItemId(int i)
        {
            return i;
        }

        private Index getGroupIndex(int pos)
        {
            int sum = 0, last = 0;

            Index index = new Index();

            for (int i = 0; i < getGroupCount(); i++)
            {
                last = sum;
                sum += (getGroupItemCount(i) + 1);

                if (pos < sum)
                {
                    index.Group = i;
                    index.Index = pos - last;
                    break;
                }
            }

            return index;
        }

        @Override
        public int getItemViewType(int position)
        {
            Index index = getGroupIndex(position);
            if(index.Index == 0)
                return -2;
            return index.Group;
        }

        @Override
        public int getViewTypeCount()
        {
            return (getGroupCount() >= 1 ? getGroupCount() : 1) * 2;
        }

        @Override
        public View getView(final int i, View view, ViewGroup viewGroup)
        {
            Index index = getGroupIndex(i);

            if (index.Index == 0)
            {
                View rView = getHeaderView(index.Group, view);
                return rView;
            }
            else
            {
                View rView = getGroupItemView(index.Group, index.Index - 1, view, viewGroup);
                return rView;
            }
        }
    }
}
